package org.jeecg.modules.mes.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.mes.entity.*;
import org.jeecg.modules.mes.mapper.MesSalaryCalculationRecordMapper;
import org.jeecg.modules.mes.service.*;
import org.jeecg.modules.mes.vo.MesSalaryCalculationVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 薪资计算服务实现
 * @Author: jeecg-boot
 * @Date: 2025-09-03
 * @Version: V1.0
 */
@Service
@Slf4j
public class MesSalaryCalculationServiceImpl extends ServiceImpl<MesSalaryCalculationRecordMapper, MesSalaryCalculationRecord> implements IMesSalaryCalculationService {

    @Autowired
    private IMesTaskParticipantService taskParticipantService;

    @Autowired
    private IMesPieceRateStandardService pieceRateStandardService;

    @Autowired
    private IMesProductionPlanTaskService productionPlanTaskService;

    @Autowired
    private IMesProductionPlanService productionPlanService;

    @Override
    @Transactional
    public MesSalaryCalculationVO calculateTaskSalary(String participantId) {
        MesSalaryCalculationVO result = new MesSalaryCalculationVO();
        
        try {
            // 获取参与者信息
            MesTaskParticipant participant = taskParticipantService.getById(participantId);
            if (participant == null) {
                result.setCalculationStatus("failed");
                result.setErrorMessage("参与者信息不存在");
                return result;
            }

            // 检查是否已完成
            if (participant.getStatus() != 2) {
                result.setCalculationStatus("failed");
                result.setErrorMessage("任务未完成，无法计算薪资");
                return result;
            }

            // 检查是否已存在薪资记录，避免重复添加
            LambdaQueryWrapper<MesSalaryCalculationRecord> existingWrapper = new LambdaQueryWrapper<>();
            existingWrapper.eq(MesSalaryCalculationRecord::getParticipantId, participantId);
            MesSalaryCalculationRecord existingRecord = this.getOne(existingWrapper);
            if (existingRecord != null) {
                result.setCalculationStatus("success");
                result.setErrorMessage("薪资记录已存在，无需重复计算");
                result.setTaskId(existingRecord.getTaskId());
                result.setParticipantId(participantId);
                result.setEmployeeId(existingRecord.getEmployeeId());
                result.setEmployeeName(existingRecord.getEmployeeName());
                result.setCalculatedSalary(existingRecord.getPieceSalary());
                return result;
            }

            //获取提交的任务、计划
            MesProductionPlanTask task = productionPlanTaskService.getById(participant.getTaskId());
            MesProductionPlan plan = productionPlanService.getById(task.getPlanId());
            if (task == null || plan == null) {
                result.setCalculationStatus("failed");
                result.setErrorMessage("任务或计划信息不存在");
                return result;
            }
            // 获取计件标准
            
            MesPieceRateStandard standard = pieceRateStandardService.getById(task.getPieceRateStandardId());
            if (standard == null) {
                result.setCalculationStatus("failed");
                result.setErrorMessage("未找到适用的计件标准");
                return result;
            }

            // 计算薪资：计件薪资 = 员工完成数量 × 基础单价
            BigDecimal pieceSalary = standard.getBaseRate()
                    .multiply(new BigDecimal(participant.getCompletedQuantity()));

            // 保存计算记录
            MesSalaryCalculationRecord record = new MesSalaryCalculationRecord();
            record.setTaskId(participant.getTaskId());
            record.setParticipantId(participantId);
            record.setEmployeeId(participant.getEmployeeId());
            record.setEmployeeName(participant.getEmployeeName());
            record.setEmployeeNo(participant.getEmployeeNo());
            record.setWorkTypeId(standard.getWorkTypeId());
            record.setWorkTypeName(standard.getWorkTypeName());
            record.setCalculationDate(new Date());
            record.setCompletedQuantity(participant.getCompletedQuantity());
            record.setBaseRate(standard.getBaseRate());
            record.setPieceSalary(pieceSalary);
            record.setCollaborationType(0); // 默认独立完成
            record.setStatus(1);
            record.setCreateTime(new Date());

            this.save(record);

            // 构建返回结果
            result.setTaskId(participant.getTaskId());
            result.setParticipantId(participantId);
            result.setEmployeeId(participant.getEmployeeId());
            result.setEmployeeName(participant.getEmployeeName());
            result.setEmployeeNo(participant.getEmployeeNo());
            result.setWorkTypeId(standard.getWorkTypeId());
            result.setWorkTypeName(standard.getWorkTypeName());
            result.setCalculationDate(new Date());
            result.setCompletedQuantity(participant.getCompletedQuantity());
            result.setBaseRate(standard.getBaseRate());
            result.setPieceSalary(pieceSalary);
            result.setCollaborationType(0);
            result.setCalculationStatus("success");

        } catch (Exception e) {
            log.error("计算薪资失败：{}", e.getMessage(), e);
            result.setCalculationStatus("failed");
            result.setErrorMessage("计算薪资失败：" + e.getMessage());
        }

        return result;
    }

    @Override
    @Transactional
    public List<MesSalaryCalculationVO> calculateBatchTaskSalary(String taskId) {
        List<MesSalaryCalculationVO> results = new ArrayList<>();
        
        // 获取任务所有参与者
        QueryWrapper<MesTaskParticipant> participantQuery = new QueryWrapper<>();
        participantQuery.eq("task_id", taskId).eq("status", 2); // 已完成状态
        
        List<MesTaskParticipant> participants = taskParticipantService.list(participantQuery);
        
        for (MesTaskParticipant participant : participants) {
            MesSalaryCalculationVO result = calculateTaskSalary(participant.getId());
            results.add(result);
        }
        
        return results;
    }

    @Override
    public List<MesSalaryCalculationVO> calculateDailySalary(String employeeId, Date calculationDate) {
        // 获取当日该员工的所有已完成任务参与记录
        QueryWrapper<MesTaskParticipant> participantQuery = new QueryWrapper<>();
        participantQuery.eq("employee_id", employeeId)
                       .eq("status", 2)
                       .apply("DATE(end_time) = DATE({0})", calculationDate);
        
        List<MesTaskParticipant> participants = taskParticipantService.list(participantQuery);
        
        return participants.stream()
                .map(participant -> calculateTaskSalary(participant.getId()))
                .collect(Collectors.toList());
    }

    @Override
    public List<MesSalaryCalculationVO> calculateMonthlySalary(String employeeId, int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1, 0, 0, 0);
        Date startDate = calendar.getTime();
        
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date endDate = calendar.getTime();
        
        List<MesSalaryCalculationRecord> records = getSalaryRecordsByEmployeeAndDateRange(employeeId, startDate, endDate);
        
        return records.stream().map(record -> {
            MesSalaryCalculationVO result = new MesSalaryCalculationVO();
            result.setTaskId(record.getTaskId());
            result.setParticipantId(record.getParticipantId());
            result.setEmployeeId(record.getEmployeeId());
            result.setEmployeeName(record.getEmployeeName());
            result.setEmployeeNo(record.getEmployeeNo());
            result.setWorkTypeId(record.getWorkTypeId());
            result.setWorkTypeName(record.getWorkTypeName());
            result.setCalculationDate(record.getCalculationDate());
            result.setCompletedQuantity(record.getCompletedQuantity());
            result.setBaseRate(record.getBaseRate());
            result.setPieceSalary(record.getPieceSalary());
            result.setCollaborationType(record.getCollaborationType());
            result.setCalculationStatus("success");
            return result;
        }).collect(Collectors.toList());
    }

    @Override
    public List<MesSalaryCalculationRecord> getSalaryRecordsByEmployeeAndDateRange(String employeeId, Date startDate, Date endDate) {
        return baseMapper.selectByEmployeeAndDateRange(employeeId, startDate, endDate);
    }

    @Override
    public List<MesSalaryCalculationRecord> getSalaryRecordsByTaskId(String taskId) {
        return baseMapper.selectByTaskId(taskId);
    }

    @Override
    public Result<?> getGroupedSalaryData(MesSalaryCalculationRecord salaryCalculationRecord, Integer pageNo, Integer pageSize, HttpServletRequest req) {
        try {
            // 构建查询条件
            QueryWrapper<MesSalaryCalculationRecord> queryWrapper = QueryGenerator.initQueryWrapper(salaryCalculationRecord, req.getParameterMap());
            
            // 按员工分组查询薪资记录
            List<MesSalaryCalculationRecord> allRecords = this.list(queryWrapper);
            
            // 按员工姓名分组
            Map<String, List<MesSalaryCalculationRecord>> groupedData = allRecords.stream()
                .collect(Collectors.groupingBy(MesSalaryCalculationRecord::getEmployeeName));
            
            // 构建树形结构数据
            List<Map<String, Object>> treeData = new ArrayList<>();
            int index = 0;
            
            for (Map.Entry<String, List<MesSalaryCalculationRecord>> entry : groupedData.entrySet()) {
                String employeeName = entry.getKey();
                List<MesSalaryCalculationRecord> records = entry.getValue();
                
                // 计算员工总薪资
                BigDecimal totalSalary = records.stream()
                    .map(MesSalaryCalculationRecord::getPieceSalary)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
                
                // 计算总完成数量
                Integer totalQuantity = records.stream()
                    .map(MesSalaryCalculationRecord::getCompletedQuantity)
                    .filter(Objects::nonNull)
                    .mapToInt(Integer::intValue)
                    .sum();
                
                // 员工汇总行（父节点）
                Map<String, Object> employeeNode = new HashMap<>();
                employeeNode.put("id", "employee_" + index);
                employeeNode.put("employeeName", employeeName);
                employeeNode.put("employeeNo", records.get(0).getEmployeeNo());
                employeeNode.put("workTypeName", "汇总");
                employeeNode.put("calculationDate", "");
                employeeNode.put("completedQuantity", totalQuantity);
                employeeNode.put("baseRate", "");
                employeeNode.put("pieceSalary", totalSalary);
                employeeNode.put("collaborationType_dictText", "");
                employeeNode.put("isParent", true);
                employeeNode.put("hasChildren", true);
                
                // 子节点（具体任务记录）
                List<Map<String, Object>> children = new ArrayList<>();
                for (MesSalaryCalculationRecord record : records) {
                    Map<String, Object> childNode = new HashMap<>();
                    childNode.put("id", record.getId());
                    childNode.put("employeeName", record.getEmployeeName());
                    childNode.put("employeeNo", record.getEmployeeNo());
                    childNode.put("workTypeName", record.getWorkTypeName());
                    childNode.put("calculationDate", record.getCalculationDate());
                    childNode.put("completedQuantity", record.getCompletedQuantity());
                    childNode.put("baseRate", record.getBaseRate());
                    childNode.put("pieceSalary", record.getPieceSalary());
                    childNode.put("collaborationType_dictText", getCollaborationTypeText(record.getCollaborationType()));
                    childNode.put("isParent", false);
                    childNode.put("taskId", record.getTaskId());
                    childNode.put("participantId", record.getParticipantId());
                    children.add(childNode);
                }
                
                employeeNode.put("children", children);
                treeData.add(employeeNode);
                index++;
            }
            
            // 分页处理
            int total = treeData.size();
            int start = (pageNo - 1) * pageSize;
            int end = Math.min(start + pageSize, total);
            List<Map<String, Object>> pagedData = treeData.subList(start, end);
            
            // 构建分页结果
            Map<String, Object> result = new HashMap<>();
            result.put("records", pagedData);
            result.put("total", total);
            result.put("size", pageSize);
            result.put("current", pageNo);
            result.put("pages", (total + pageSize - 1) / pageSize);
            
            return Result.OK(result);
            
        } catch (Exception e) {
            log.error("获取分组薪资数据失败", e);
            return Result.error("获取分组薪资数据失败：" + e.getMessage());
        }
    }
    
    private String getCollaborationTypeText(Integer collaborationType) {
        if (collaborationType == null) return "";
        switch (collaborationType) {
            case 0: return "独立完成";
            case 1: return "协作完成";
            default: return "";
        }
    }
}
